Skip to main content

Production-Level Spring Boot Folder Structure

Complete Project Structureโ€‹

project-root/
โ”œโ”€โ”€ src/
โ”‚ โ”œโ”€โ”€ main/
โ”‚ โ”‚ โ”œโ”€โ”€ java/
โ”‚ โ”‚ โ”‚ โ””โ”€โ”€ com/
โ”‚ โ”‚ โ”‚ โ””โ”€โ”€ company/
โ”‚ โ”‚ โ”‚ โ””โ”€โ”€ project/
โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ ProjectApplication.java
โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ config/
โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ controller/
โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ service/
โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ repository/
โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ model/
โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ dto/
โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ mapper/
โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ exception/
โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ security/
โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ util/
โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ validator/
โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ aspect/
โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ event/
โ”‚ โ”‚ โ”‚ โ””โ”€โ”€ constant/
โ”‚ โ”‚ โ””โ”€โ”€ resources/
โ”‚ โ”‚ โ”œโ”€โ”€ application.yml
โ”‚ โ”‚ โ”œโ”€โ”€ application-dev.yml
โ”‚ โ”‚ โ”œโ”€โ”€ application-prod.yml
โ”‚ โ”‚ โ”œโ”€โ”€ application-test.yml
โ”‚ โ”‚ โ”œโ”€โ”€ db/
โ”‚ โ”‚ โ”‚ โ””โ”€โ”€ migration/
โ”‚ โ”‚ โ”œโ”€โ”€ static/
โ”‚ โ”‚ โ”œโ”€โ”€ templates/
โ”‚ โ”‚ โ”œโ”€โ”€ i18n/
โ”‚ โ”‚ โ””โ”€โ”€ logback-spring.xml
โ”‚ โ””โ”€โ”€ test/
โ”‚ โ”œโ”€โ”€ java/
โ”‚ โ”‚ โ””โ”€โ”€ com/
โ”‚ โ”‚ โ””โ”€โ”€ company/
โ”‚ โ”‚ โ””โ”€โ”€ project/
โ”‚ โ”‚ โ”œโ”€โ”€ controller/
โ”‚ โ”‚ โ”œโ”€โ”€ service/
โ”‚ โ”‚ โ”œโ”€โ”€ repository/
โ”‚ โ”‚ โ”œโ”€โ”€ integration/
โ”‚ โ”‚ โ””โ”€โ”€ unit/
โ”‚ โ””โ”€โ”€ resources/
โ”‚ โ””โ”€โ”€ application-test.yml
โ”œโ”€โ”€ docker/
โ”‚ โ”œโ”€โ”€ Dockerfile
โ”‚ โ”œโ”€โ”€ docker-compose.yml
โ”‚ โ””โ”€โ”€ docker-compose.dev.yml
โ”œโ”€โ”€ docs/
โ”‚ โ”œโ”€โ”€ API.md
โ”‚ โ”œโ”€โ”€ DEPLOYMENT.md
โ”‚ โ””โ”€โ”€ ARCHITECTURE.md
โ”œโ”€โ”€ scripts/
โ”‚ โ”œโ”€โ”€ deploy.sh
โ”‚ โ”œโ”€โ”€ backup.sh
โ”‚ โ””โ”€โ”€ healthcheck.sh
โ”œโ”€โ”€ .github/
โ”‚ โ””โ”€โ”€ workflows/
โ”‚ โ”œโ”€โ”€ ci.yml
โ”‚ โ””โ”€โ”€ cd.yml
โ”œโ”€โ”€ .gitignore
โ”œโ”€โ”€ README.md
โ”œโ”€โ”€ pom.xml (or build.gradle)
โ”œโ”€โ”€ Dockerfile
โ””โ”€โ”€ docker-compose.yml

Detailed Layer Breakdownโ€‹

1. Controller Layer (controller/)โ€‹

Handles HTTP requests and responses. Should be thin and delegate business logic to services.

// UserController.java
@RestController
@RequestMapping("/api/v1/users")
@Validated
public class UserController {
// REST endpoints
}

Responsibilities:

  • Request/response handling
  • Input validation
  • HTTP status codes
  • Delegating to service layer

Naming Convention: {Entity}Controller.java


2. Service Layer (service/)โ€‹

Contains business logic and orchestrates operations.

service/
โ”œโ”€โ”€ UserService.java (interface)
โ”œโ”€โ”€ impl/
โ”‚ โ””โ”€โ”€ UserServiceImpl.java
โ”œโ”€โ”€ AuthenticationService.java
โ””โ”€โ”€ EmailService.java

Responsibilities:

  • Business logic implementation
  • Transaction management
  • Service orchestration
  • Calling multiple repositories

Best Practices:

  • Use interfaces for service contracts
  • Keep implementations in impl/ subdirectory
  • Use @Transactional annotations appropriately

3. Repository Layer (repository/)โ€‹

Data access layer using Spring Data JPA or other persistence mechanisms.

// UserRepository.java
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
Optional<User> findByEmail(String email);
List<User> findByStatus(UserStatus status);
}

Responsibilities:

  • Database operations
  • Custom queries
  • Data persistence

Types:

  • JPA Repositories
  • Custom Repository implementations
  • Query methods

4. Model/Entity Layer (model/ or entity/)โ€‹

JPA entities representing database tables.

// User.java
@Entity
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@Column(nullable = false, unique = true)
private String email;

// getters, setters, builders
}

Annotations Used:

  • @Entity, @Table
  • @Id, @GeneratedValue
  • @OneToMany, @ManyToOne, etc.
  • @Column, @JoinColumn

5. DTO Layer (dto/)โ€‹

Data Transfer Objects for API requests and responses.

dto/
โ”œโ”€โ”€ request/
โ”‚ โ”œโ”€โ”€ CreateUserRequest.java
โ”‚ โ””โ”€โ”€ UpdateUserRequest.java
โ””โ”€โ”€ response/
โ”œโ”€โ”€ UserResponse.java
โ””โ”€โ”€ ApiResponse.java

Purpose:

  • Decouple API contract from domain models
  • Validation annotations
  • Version control of APIs
  • Hide sensitive entity data
// CreateUserRequest.java
public class CreateUserRequest {
@NotBlank
@Email
private String email;

@Size(min = 8)
private String password;
}

6. Mapper Layer (mapper/)โ€‹

Converts between entities and DTOs.

// UserMapper.java
@Mapper(componentModel = "spring")
public interface UserMapper {
UserResponse toResponse(User user);
User toEntity(CreateUserRequest request);
List<UserResponse> toResponseList(List<User> users);
}

Options:

  • MapStruct (recommended for production)
  • Manual mapping
  • ModelMapper library

7. Configuration Layer (config/)โ€‹

Application configuration classes.

config/
โ”œโ”€โ”€ SecurityConfig.java
โ”œโ”€โ”€ DatabaseConfig.java
โ”œโ”€โ”€ CacheConfig.java
โ”œโ”€โ”€ AsyncConfig.java
โ”œโ”€โ”€ SwaggerConfig.java
โ””โ”€โ”€ RestTemplateConfig.java

Common Configurations:

  • Security (Spring Security)
  • Database (DataSource, JPA)
  • Caching (Redis, Caffeine)
  • Async processing
  • API documentation (Swagger/OpenAPI)
  • CORS settings

8. Exception Layer (exception/)โ€‹

Custom exceptions and global exception handling.

exception/
โ”œโ”€โ”€ BusinessException.java
โ”œโ”€โ”€ ResourceNotFoundException.java
โ”œโ”€โ”€ ValidationException.java
โ”œโ”€โ”€ UnauthorizedException.java
โ””โ”€โ”€ GlobalExceptionHandler.java
// GlobalExceptionHandler.java
@RestControllerAdvice
public class GlobalExceptionHandler {

@ExceptionHandler(ResourceNotFoundException.class)
public ResponseEntity<ErrorResponse> handleNotFound(
ResourceNotFoundException ex) {
return ResponseEntity.status(HttpStatus.NOT_FOUND)
.body(new ErrorResponse(ex.getMessage()));
}
}

9. Security Layer (security/)โ€‹

Authentication and authorization components.

security/
โ”œโ”€โ”€ JwtTokenProvider.java
โ”œโ”€โ”€ JwtAuthenticationFilter.java
โ”œโ”€โ”€ CustomUserDetailsService.java
โ”œโ”€โ”€ SecurityUtils.java
โ””โ”€โ”€ PasswordEncoderConfig.java

Components:

  • JWT token handling
  • Custom authentication filters
  • User details service
  • Security utilities

10. Util Layer (util/)โ€‹

Utility and helper classes.

util/
โ”œโ”€โ”€ DateUtils.java
โ”œโ”€โ”€ StringUtils.java
โ”œโ”€โ”€ ValidationUtils.java
โ””โ”€โ”€ ResponseBuilder.java

Guidelines:

  • Static utility methods
  • No business logic
  • Reusable across layers

11. Validator Layer (validator/)โ€‹

Custom validation logic.

validator/
โ”œโ”€โ”€ EmailValidator.java
โ”œโ”€โ”€ PhoneNumberValidator.java
โ””โ”€โ”€ annotation/
โ”œโ”€โ”€ ValidEmail.java
โ””โ”€โ”€ ValidPhone.java

12. Aspect Layer (aspect/)โ€‹

Cross-cutting concerns using AOP.

aspect/
โ”œโ”€โ”€ LoggingAspect.java
โ”œโ”€โ”€ PerformanceAspect.java
โ””โ”€โ”€ SecurityAspect.java

Use Cases:

  • Logging
  • Performance monitoring
  • Transaction management
  • Security checks

13. Event Layer (event/)โ€‹

Event-driven architecture components.

event/
โ”œโ”€โ”€ UserCreatedEvent.java
โ”œโ”€โ”€ OrderPlacedEvent.java
โ”œโ”€โ”€ listener/
โ”‚ โ”œโ”€โ”€ UserEventListener.java
โ”‚ โ””โ”€โ”€ OrderEventListener.java
โ””โ”€โ”€ publisher/
โ””โ”€โ”€ EventPublisher.java

14. Constant Layer (constant/)โ€‹

Application constants and enums.

constant/
โ”œโ”€โ”€ AppConstants.java
โ”œโ”€โ”€ ErrorMessages.java
โ”œโ”€โ”€ ApiEndpoints.java
โ””โ”€โ”€ enums/
โ”œโ”€โ”€ UserStatus.java
โ”œโ”€โ”€ OrderStatus.java
โ””โ”€โ”€ Role.java

Resources Directory Structureโ€‹

Application Propertiesโ€‹

# application.yml (base configuration)
spring:
application:
name: project-name
profiles:
active: ${ACTIVE_PROFILE:dev}

# application-dev.yml (development)
spring:
datasource:
url: jdbc:postgresql://localhost:5432/devdb

# application-prod.yml (production)
spring:
datasource:
url: ${DB_URL}
username: ${DB_USERNAME}
password: ${DB_PASSWORD}

Database Migrations (db/migration/)โ€‹

Using Flyway or Liquibase:

db/
โ””โ”€โ”€ migration/
โ”œโ”€โ”€ V1__create_users_table.sql
โ”œโ”€โ”€ V2__create_orders_table.sql
โ””โ”€โ”€ V3__add_user_status_column.sql

Testing Structureโ€‹

Unit Testsโ€‹

test/
โ””โ”€โ”€ java/
โ””โ”€โ”€ com/company/project/
โ”œโ”€โ”€ service/
โ”‚ โ””โ”€โ”€ UserServiceTest.java
โ””โ”€โ”€ util/
โ””โ”€โ”€ DateUtilsTest.java

Integration Testsโ€‹

integration/
โ”œโ”€โ”€ UserIntegrationTest.java
โ”œโ”€โ”€ OrderFlowIntegrationTest.java
โ””โ”€โ”€ config/
โ””โ”€โ”€ TestConfig.java

Docker Configurationโ€‹

Dockerfileโ€‹

FROM eclipse-temurin:17-jdk-alpine AS build
WORKDIR /workspace/app
COPY mvnw .
COPY .mvn .mvn
COPY pom.xml .
COPY src src
RUN ./mvnw install -DskipTests

FROM eclipse-temurin:17-jre-alpine
VOLUME /tmp
ARG DEPENDENCY=/workspace/app/target/dependency
COPY --from=build ${DEPENDENCY}/BOOT-INF/lib /app/lib
COPY --from=build ${DEPENDENCY}/META-INF /app/META-INF
COPY --from=build ${DEPENDENCY}/BOOT-INF/classes /app
ENTRYPOINT ["java","-cp","app:app/lib/*","com.company.project.ProjectApplication"]

docker-compose.ymlโ€‹

version: '3.8'
services:
app:
build: .
ports:
- "8080:8080"
environment:
- SPRING_PROFILES_ACTIVE=prod
depends_on:
- postgres
- redis

postgres:
image: postgres:15
environment:
POSTGRES_DB: appdb
POSTGRES_USER: user
POSTGRES_PASSWORD: password
volumes:
- postgres_data:/var/lib/postgresql/data

redis:
image: redis:7-alpine
ports:
- "6379:6379"

volumes:
postgres_data:

Best Practices Summaryโ€‹

Package Organizationโ€‹

  • Use feature-based or layer-based organization consistently
  • Keep packages cohesive and loosely coupled
  • Avoid circular dependencies

Naming Conventionsโ€‹

  • Controllers: {Entity}Controller
  • Services: {Entity}Service and {Entity}ServiceImpl
  • Repositories: {Entity}Repository
  • DTOs: {Purpose}{Entity}Request/Response

Securityโ€‹

  • Never commit secrets to version control
  • Use environment variables for sensitive data
  • Implement proper authentication and authorization
  • Use HTTPS in production

Performanceโ€‹

  • Implement caching strategically
  • Use connection pooling
  • Optimize database queries
  • Use async processing for long-running tasks

Monitoringโ€‹

  • Implement health checks
  • Add application metrics (Micrometer/Prometheus)
  • Use structured logging
  • Set up alerting

Documentationโ€‹

  • Maintain updated README
  • Document API using OpenAPI/Swagger
  • Keep architecture documentation current
  • Add inline comments for complex logic

Additional Production Considerationsโ€‹

CI/CD Pipelineโ€‹

  • Automated testing
  • Code quality checks (SonarQube)
  • Security scanning
  • Automated deployment

Monitoring & Loggingโ€‹

  • Centralized logging (ELK stack)
  • APM tools (New Relic, Datadog)
  • Health check endpoints
  • Custom metrics

Database Managementโ€‹

  • Migration scripts (Flyway/Liquibase)
  • Backup strategies
  • Read replicas for scaling
  • Connection pooling (HikariCP)

API Versioningโ€‹

/api/v1/users
/api/v2/users

Rate Limiting & Throttlingโ€‹

  • Implement request rate limiting
  • Use API gateway when scaling

This structure provides a solid foundation for building production-ready Spring Boot applications that are maintainable, scalable, and follow industry best practices.